
#include "rtklib.h"

static const char rcsid[]="$Id:$";

#define PRGNAME     "str2str"          /* program name */
#define MAXSTR      5                  /* max number of streams */
#define TRFILE      "str2str.trace"    /* trace file */

/* global variables ----------------------------------------------------------*/
static strsvr_t strsvr;                /* stream server */
static volatile int intrflg=0;         /* interrupt flag */
static char srctbl[1024]="";           /* source table file */

/* decode format -------------------------------------------------------------*/
static void decodefmt(char *path, int *fmt)
{
    char *p;

    *fmt=-1;

    if ((p=strrchr(path,'#'))) {
        if      (!strcmp(p,"#rtcm2")) *fmt=STRFMT_RTCM2;
        else if (!strcmp(p,"#rtcm3")) *fmt=STRFMT_RTCM3;
        else if (!strcmp(p,"#binex")) *fmt=STRFMT_BINEX;
        else return;
        *p='\0';
    }
}
/* decode stream path --------------------------------------------------------*/
static int decodepath(const char *path, int *type, char *strpath, int *fmt)
{
    char buff[1024],*p;

    strcpy(buff,path);

    /* decode format */
    decodefmt(buff,fmt);

    /* decode type */
    if (!(p=strstr(buff,"://"))) {
        strcpy(strpath,buff);
        *type=STR_FILE;
        return 1;
    }
    if      (!strncmp(path,"serial",  6)) *type=STR_SERIAL;
    else if (!strncmp(path,"tcpsvr",  6)) *type=STR_TCPSVR;
    else if (!strncmp(path,"tcpcli",  6)) *type=STR_TCPCLI;
    else if (!strncmp(path,"ntripc_s",8)) *type=STR_NTRIPC_S;
    else if (!strncmp(path,"ntripc_c",8)) *type=STR_NTRIPC_C;
    else if (!strncmp(path,"ntrips",  6)) *type=STR_NTRIPSVR;
    else if (!strncmp(path,"ntrip",   5)) *type=STR_NTRIPCLI;
    else if (!strncmp(path,"file",    4)) *type=STR_FILE;
    else {
        fprintf(stderr,"stream path error: %s\n",buff);
        return 0;
    }
    strcpy(strpath,p+3);
    return 1;
}
/* read receiver commands ----------------------------------------------------*/
static void readcmd(const char *file, char *cmd, int type)
{
    FILE *fp;
    char buff[MAXSTR],*p=cmd;
    int i=0;

    *p='\0';

    if (!(fp=fopen(file,"r"))) return;

    while (fgets(buff,sizeof(buff),fp)) {
        if (*buff=='@') i++;
        else if (i==type&&p+strlen(buff)+1<cmd+MAXRCVCMD) {
            p+=sprintf(p,"%s",buff);
        }
    }
    fclose(fp);
}

// FILE *fpout;
SOCKET sock_fd;

extern void up(char *msg, int flag)
{
    send(sock_fd, msg, strlen(msg), 0);
}

void stopClient(){
    intrflg = 1;
}

int startClient(char *mountPoint, char *casterIP, char *casterPort,
        char *casterUser, char *casterPassW, char *sockedIP, char *sockedPort)
{
    memset(strsvr.mountpoint,0x00,sizeof(strsvr.mountpoint));
    strncpy(strsvr.mountpoint,mountPoint,sizeof(mountPoint));
    sock_fd = openSocked(sockedIP,sockedPort);
    getObsNav(mountPoint,casterIP,casterPort,casterUser,casterPassW);
    return 0;
}

void getObsNav(char *mountpoint, char *ip, char *port, char *username, char *password)
{
    char ntrip[1024] = {"\0"};
    sprintf(ntrip,"ntrip://%s:%s@%s:%s/%s#rtcm3",username,password,ip,port,mountpoint);
    toDecode(ntrip);
}

extern int toDecode(char *ntrip)
{
    static char cmd_strs[MAXSTR][MAXRCVCMD]={"","","","",""};
    static char cmd_periodic_strs[MAXSTR][MAXRCVCMD]={"","","","",""};
    const char ss[]={'E','-','W','C','C'};
    strconv_t *conv[MAXSTR]={NULL};
    double stapos[3]={0},stadel[3]={0};
    char *paths[MAXSTR],s[MAXSTR][MAXSTRPATH]={{0}};
    char *cmdfile[MAXSTR]={"","","","",""},*cmds[MAXSTR],*cmds_periodic[MAXSTR];
    char *local="",*proxy="",*msg="1004,1019,1046,1126",*opt="",buff[256],*p;
    char strmsg[MAXSTRMSG]="",*antinfo="",*rcvinfo="";
    char *ant[]={"","",""},*rcv[]={"","",""},*logfile="";
    int i,j,n=0,dispint=1000,trlevel=0,opts[]={10000,10000,2000,32768,10,0,30,0};
    int types[MAXSTR]={STR_FILE,STR_FILE},stat[MAXSTR]={0},byte[MAXSTR]={0};
    int bps[MAXSTR]={0},fmts[MAXSTR]={0},sta=0;

    int argc = 5;

    char argv[][1024] = {" ","-in","","-out","tcpsvr://:8668#rtcm3"};
    sprintf(argv[2],"%s",ntrip);

    for (i=0;i<MAXSTR;i++) {
        paths[i]=s[i];
        cmds[i]=cmd_strs[i];
        cmds_periodic[i]=cmd_periodic_strs[i];
    }
    for (i=1;i<argc;i++) {
        if (!strcmp(argv[i],"-in")&&i+1<argc) {
            if (!decodepath(argv[++i],types,paths[0],fmts)) return -1;
        }
        else if (!strcmp(argv[i],"-out")&&i+1<argc&&n<MAXSTR-1) {
            if (!decodepath(argv[++i],types+n+1,paths[n+1],fmts+n+1)) return -1;
            n++;
        }
    }
    if (n<=0) n=1; /* stdout */

    for (i=0;i<n;i++) {
        if (fmts[i+1]<=0) continue;
        if (fmts[i+1]!=STRFMT_RTCM3) {
            fprintf(stderr,"unsupported output format\n");
            return -1;
        }
        if (fmts[0]<0) {
            fprintf(stderr,"specify input format\n");
            return -1;
        }
        if (!(conv[i]=strconvnew(fmts[0],fmts[i+1],msg,sta,sta!=0,opt))) {
            fprintf(stderr,"stream conversion error\n");
            return -1;
        }
        strcpy(buff,antinfo);
        for (p=strtok(buff,","),j=0;p&&j<3;p=strtok(NULL,",")) ant[j++]=p;
        strcpy(conv[i]->out.sta.antdes,ant[0]);
        strcpy(conv[i]->out.sta.antsno,ant[1]);
        conv[i]->out.sta.antsetup=atoi(ant[2]);
        strcpy(buff,rcvinfo);
        for (p=strtok(buff,","),j=0;p&&j<3;p=strtok(NULL,",")) rcv[j++]=p;
        strcpy(conv[i]->out.sta.rectype,rcv[0]);
        strcpy(conv[i]->out.sta.recver ,rcv[1]);
        strcpy(conv[i]->out.sta.recsno ,rcv[2]);
        matcpy(conv[i]->out.sta.pos,stapos,3,1);
        matcpy(conv[i]->out.sta.del,stadel,3,1);
    }

    strsvrinit(&strsvr,n+1);
    if (trlevel>0) {
        traceopen(*logfile?logfile:TRFILE);
        tracelevel(trlevel);
    }
    fprintf(stderr,"stream server start\n");

    strsetdir(local);
    strsetproxy(proxy);

    for (i=0;i<MAXSTR;i++) {
        if (*cmdfile[i]) readcmd(cmdfile[i],cmds[i],0);
        if (*cmdfile[i]) readcmd(cmdfile[i],cmds_periodic[i],2);
    }
    /* start stream server */
    if (!strsvrstart(&strsvr,opts,types,paths,conv,cmds,cmds_periodic,stapos)) {
        fprintf(stderr,"stream server start error\n");
        return -1;
    }
    /* read and set ntrip source table */
    if (*srctbl) {
        strsvrsetsrctbl(&strsvr,srctbl);
    }

    for (intrflg=0;!intrflg;) {

        /* get stream server status */
        strsvrstat(&strsvr,stat,byte,bps,strmsg);

        /* show stream server status */
        for (i=0,p=buff;i<MAXSTR;i++) p+=sprintf(p,"%c",ss[stat[i]+1]);
        
        /*fprintf(stderr,"%s [%s] %10d B %7d bps %s\n",
                time_str(utc2gpst(timeget()),0),buff,byte[0],bps[0],strmsg);*/

        sleepms(dispint);
    }
    for (i=0;i<MAXSTR;i++) {
        if (*cmdfile[i]) readcmd(cmdfile[i],cmds[i],1);
    }
    /* stop stream server */
    strsvrstop(&strsvr,cmds);
    // fclose(fpout);

    for (i=0;i<n;i++) {
        strconvfree(conv[i]);
    }
    if (trlevel>0) {
        traceclose();
    }
    WSACleanup();
    fprintf(stderr,"stream server stop\n");
    return 0;
}
